#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

#include <iostream>

using namespace std;

const static char* WORDS[] = {
    "contrive", "hum",          "imperil", "lade",   "addition",
    "blow",     "chance",       "mouth",   "pocket", "punishment",
    "rest",     "adjoining",    "alive",   "brown",  "feeble",
    "jolly",    "parsimonious", "sweet",   "tawdry", "verdant",
};

#define PIPEFILE "pipenamed"

int main(int argc, char const* argv[]) {
  srand(time(NULL));
  // 创建有名管道
  if (mkfifo(PIPEFILE, 0666) < 0) {
    perror("Error For mkfifo");
    return 1;
  }

  pid_t pid = fork();
  if (pid < 0) {
    perror("Error For fork");
    return 1;
  } else if (pid == 0) {
    cout << "SUB PIPE OPEN" << endl;
    // 打开有名管道文件
    int pfd = open(PIPEFILE, O_WRONLY);
    if (pfd < 0) {
      perror("Error For open");
      return 1;
    }
    for (int i = 0; i < 5; ++i) {
      char buff[128]{0};
      snprintf(buff, 128, "SUB[%d] -> %s", getpid(), WORDS[rand() % 20]);
      // 子进程往管道内写入
      if (write(pfd, buff, 128) < 0) {
        perror("Error For write");
      }
      // 强制同步写入数据
      sync();
    }
    cout << "SUB FINISH" << endl;
    close(pfd);
    exit(0);
  }
  cout << "MAIN PIPE OPEN" << endl;
  int pfd = open(PIPEFILE, O_RDONLY);
  if (pfd < 0) {
    perror("Error For open");
    return 1;
  }
  char buff[1024]{0};
  while (1) {
    // 父进程从管道中读取
    ssize_t size = read(pfd, buff, 1024);
    if (size > 0) {
      cout << "MAIN[" << getpid() << "] <- " << buff << endl;
    } else if (size == 0) {
      break;
    }
  }
  cout << "MAIN FINISH" << endl;
  // 关闭管道文件
  close(pfd);
  // 删除管道文件
  unlink(PIPEFILE);
  return 0;
}
